package com.mew.common.dc.redis;

import cn.hutool.core.util.StrUtil;
import com.mew.common.config.RedisConstantValue;
import com.mew.common.entity.config.Game;
import com.mew.common.entity.config.Room;
import com.mew.common.entity.game.Jackport;
import com.mew.common.entity.game.RoomProfile;
import com.mew.common.exception.ResponseCode;
import com.mew.common.rest.PlayingMessage;
import com.zebra.common.TmsServerType;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.stereotype.Service;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;


@Service
@Slf4j
public class GameRoomRedisService {

    @Autowired
    private RedisTemplate<String, Object> redisTemplate;

    @Autowired
    private DefaultRedisScript<Long> jackpotScript;

    //下线的游戏， 直接从redis 移除 ；  如果房间关闭完了 则游戏也自动关闭
    public List<Game> findAllGame(){
        List<Object> values = redisTemplate.opsForHash().values(RedisConstantValue.GAMECONF_GAME);
        if (null == values || values.isEmpty()){
            return null;
        }
        return values.stream().map(o -> (Game)o).collect(Collectors.toList());
    }

    public List<Game> findGameByType(TmsServerType gameServerType){
        List<Object> values = redisTemplate.opsForHash().values(RedisConstantValue.GAMECONF_GAME);
        if (null == values || values.isEmpty()){
            return null;
        }
        return values.stream().map(o -> (Game)o).filter(game -> gameServerType.code() == game.getGameType()).collect(Collectors.toList());
    }



    public Game getRedisGame(int gameId){
        if (gameId <1){
            return null;
        }
        return  (Game) redisTemplate.opsForHash().get(RedisConstantValue.GAMECONF_GAME, gameId);
    }

    public long getGameSize(){
        return redisTemplate.opsForHash().size(RedisConstantValue.GAMECONF_GAME);
    }

    public String getGameVfx(int gameId){
        Game game = getRedisGame(gameId);
        return game.getGameVfx();
    }

    //-----------room--------------
    public List<Room> findRoomByGameId(int gameId){
        if (gameId <1){
            return null;
        }
        List<Object> list = redisTemplate.opsForList().range(String.format(RedisConstantValue.GAMECONF_ROOM_LIST, gameId), 0, -1);
        if (null == list || list.isEmpty()){
            return null;
        }
        return list.stream().map(o -> (Room)o).collect(Collectors.toList());
    }

    public Room getRedisRoom(int gameId, int roomId){
        if (roomId <1){
            return null;
        }
        List<Room> list = findRoomByGameId(gameId);
        if (null == list || list.isEmpty()){
            return null;
        }
       return list.stream().filter(r -> roomId == r.getId()).findFirst().orElse(null);
    }

    public void removeRedisRoom(Room room){
        redisTemplate.opsForList().remove(String.format(RedisConstantValue.GAMECONF_ROOM_LIST, room.getGameId()), 1, room);
    }


    public PlayingMessage getPlayInfo(int gameId, int roomId){
        Game game = getRedisGame(gameId);
        Room room = getRedisRoom(gameId, roomId);
        if (null == game || room == null){
            return PlayingMessage.builder().stateCode(ResponseCode.GameServerNotConfig.code()).build();
        }
       return PlayingMessage.builder()
               .gameId(gameId)
               .roomId(roomId)
               .gameType(game.getGameType())
               .stateCode(ResponseCode.Success.code())
               .build();
    }


    public RoomProfile getRoomProfile(int roomId){
        return (RoomProfile) redisTemplate.opsForHash().get(RedisConstantValue.GAMECONF_ROOM_PROFILE, roomId);
    }

    /**
     * @param roomId
     * @param jackpot 正数 扣奖池 ， 负数 还奖池
     * @return  true : 奖池可以 出奖；  false:  奖池没钱了
     */
    public boolean jackpot(int roomId, long jackpot){
        log.info("Jackpot :  roomId {}, jackpot {}",   roomId, jackpot);
        long res = redisTemplate.execute(jackpotScript, Arrays.asList(String.valueOf(roomId)), jackpot );
        return  res > 0 ? true : false;
    }

    /**
     * 通过房间 获取奖池
     */
    public List<Jackport> findJackPortByRoomId(int roomId){
        List<Object> list = redisTemplate.opsForHash().values(String.format(RedisConstantValue.GAMECONF_ROOM_JACKPOT_REAL, roomId));
        if (null == list || list.isEmpty()){
            return null;
        }
        return list.stream().map(o -> (Jackport)o).collect(Collectors.toList());
    }

    /**
     * 获取单个奖池
     * @param roomId roomId
     * @param no 奖池编号
     * @return
     */
    public Jackport findJackPortOne(int roomId,int no){
        Object o = redisTemplate.opsForHash().get(String.format(RedisConstantValue.GAMECONF_ROOM_JACKPOT_REAL, roomId), no);
        if(null==o){
            return null;
        }
        return (Jackport)o;
    }
    public void updateJackPort(int roomId,Jackport jackport){
        redisTemplate.opsForHash().put(String.format(RedisConstantValue.GAMECONF_ROOM_JACKPOT_REAL, roomId),jackport.getNo(),jackport);
    }



    /**
     *
     * @param gameId
     * @param roomId
     * @return
     */
    public boolean isCapacityControl(int gameId, int roomId){
        return false;
    }


}
